<?php

namespace app\admin\model\shop\market\coupon;

use app\admin\model\shop\user\UserCoupon;
use app\shop\enums\coupon\CouponStatus;
use ba\Exception;
use think\Model;
use think\model\concern\SoftDelete;
use think\model\relation\HasMany;

/**
 * Coupon
 */
class Coupon extends Model
{
    use SoftDelete;

    protected $defaultSoftDelete = 0;

    // 表名
    protected $name = 'shop_coupon';

    // 自动写入时间戳字段
    protected $autoWriteTimestamp = true;

    // 字段类型转换
    protected $type = [
        'delete_time'     => 'timestamp:Y-m-d H:i:s',
        'discount_amount' => 'float',
        'discount_ratio'  => 'float',
        'min_price'       => 'float',
    ];

    public function userCoupon(): HasMany
    {
        return $this->hasMany(UserCoupon::class, 'coupon_id', 'id');
    }

    /**
     * 写入前
     * @param Model $model
     * @return Model
     * @throws Exception
     */
    public static function onBeforeWrite(Model $model): Model
    {
        if ($model->start_time > $model->end_time) {
            throw new Exception('优惠券开始时间不能小于结束时间');
        }

        return $model;
    }

    public static function onBeforeInsert(Model $model): Model
    {
        $model->discount_ratio *= 0.1;

        return $model;
    }

    public static function onBeforeUpdate(Model $model): Model
    {
        $model->discount_ratio = $model->getData('discount_ratio') * 0.1;
        // dd($model->toArray());
        return $model;
    }

    protected static function onAfterInsert($model): void
    {
        if ($model->weigh == 0) {
            $pk = $model->getPk();
            if (strlen($model[$pk]) >= 19) {
                $model->where($pk, $model[$pk])->update(['weigh' => $model->count()]);
            } else {
                $model->where($pk, $model[$pk])->update(['weigh' => $model[$pk]]);
            }
        }
    }

    public static function onAfterUpdate(Model $model): void
    {
        if ($model->getData('status') == 1) {
            $model->userCoupon()
                ->whereBetweenTimeField('start_time', 'end_time')
                ->where('status', CouponStatus::INVALID)
                ->update(['status' => CouponStatus::TO_USE]);
        } else {
            $model->userCoupon()->where('status', CouponStatus::TO_USE)->update(['status' => CouponStatus::INVALID]);
        }
    }

    public function getRangeGoodsIdsAttr($value): array|bool
    {
        if (!$value) {
            return [];
        }

        return explode(',', $value);
    }

    public function setRangeGoodsIdsAttr($value): string
    {
        return implode(',', $value);
    }

    public function getDiscountRatioAttr($value): string
    {
        $value = bcmul($value, 10, 1);

        if (str_ends_with($value, '.0')) {
            $value = rtrim($value, '.0');
        }

        return $value;
    }
}